<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Db_field
{	
	protected $field_properties = array(
		'data_type' => '', // INT, CHAR, etc...
		'data_length' => '',
		'data_decimals_length' => '', // for float
		'data_values' => '', // for set and enum
		'default_value' => '',
		'allow_null' => true, // T/F
		'auto_increment' => false, // T/F
		'unique_key' => false, // T/F
		'primary_key' => false, // T/F
		'unsigned' => false, // T/F
		'current_timestamp' => false, // T/F (timestamp field only)
		'index' => false, // T/F
		'comments' => '', // comments on the field
		'field_name' => '', // Literal name of the field, for use in DB or HTML
		'field_id' => '', // ID for use in HTML fields (auto-generated)
		'friendly_field_name' => '', // Name for display in admin section (auto-generated)
		'help_text' => '', // Pop-up from ? icon in Admin
		'value' => null // The actual value the field holds
	);
	
	public function __construct(Array $properties)
	{
		// Set user specified data
		$this->set_properties($properties);
	} // end __construct
	
	public function __get($name) 
	{
		$return = null; // Default case
		
		if (array_key_exists($name, $this->field_properties))
		{
			$return = $this->field_properties[$name];
		}
		else
		{
			$trace = debug_backtrace();
			trigger_error(
				'Undefined property via __get(): ' . $name .
				' in ' . $trace[0]['file'] .
				' on line ' . $trace[0]['line'],
				E_USER_NOTICE
			);
		}
		
		return $return;
	} // end __get
	
	/**
	 * set_properties:
	 * This function sets the protected properties of this class to the given values.
	 * This is primarily intended for easy initialization.
	 * 
	 * @param object $properties
	 */
	protected function set_properties(Array $properties)
	{
		$this->field_properties = array_merge($this->field_properties, $properties);
	} // end set_properties
	
	
	public function get_properties($convert_values = false)
	{
		$field_properties = $this->field_properties;
		
		if($convert_values)
		{
			$field_properties['data_values'] = $this->convert_data_values_for_enum();
		}
		
		return $field_properties;
	} // end get_properties
	
	
	/**
	 * get_type:
	 * Return the data type (INT, CHAR, etc...).
	 * 
	 * @return string data_type
	 */
	public function get_type()
	{
		return $this->field_properties['data_type'];
	} // end get_type
	
	
	public function get_field_name()
	{
		return $this->field_properties['field_name'];
	} // end get_field_name
	
	
	public function get_field_id()
	{
		if(strlen($this->field_properties['field_id']))
		{
			$field_id = $this->field_properties['field_id'];
		}
		else
		{
			$field_id = $this->field_properties['field_name'];
		}
		
		return $field_id;
	} // end get_field_id
	
	
	public function get_friendly_name()
	{
		if(strlen($this->field_properties['friendly_field_name']))
		{
			$friendly_name = $this->field_properties['friendly_field_name'];
		}
		else
		{
			$friendly_name = ucwords(str_replace('_', ' ', $this->field_properties['field_name']));
		}
		return $friendly_name;
	} // end get_friendly_name
	
	
	
	public function get_default()
	{
		return $this->field_properties['default_value'];
	} // end get_default
	
	
	public function get_help_text()
	{
		return $this->field_properties['help_text'];
	} // end get_help_text
	
	
	/**
	 * is_primary:
	 * Return whether or not this field is a primary key.
	 * 
	 * @return bool
	 */
	public function is_primary()
	{
		return $this->field_properties['primary_key'];
	} // end is_primary
	
	
	/**
	 * is_indexed:
	 * Return whether or not this field has an index.
	 * 
	 * @return bool
	 */
	public function is_indexed()
	{
		return $this->field_properties['index'];
	} // end is_indexed
	
	
	public function is_auto_increment()
	{
		return $this->field_properties['auto_increment'];
	} // end is_auto_increment
	
	public function is_null_allowed()
	{
		return $this->field_properties['allow_null'];
	} // end is_null_allowed
	
	
	public function get_field_definition()
	{
		// Start with the minimum required: type
		$return = array(
			'type' => $this->field_properties['data_type']
		);
		
		// Check to see if there is a constraint we are applying
		if(strlen($this->field_properties['data_length']))
		{
			$return['constraint'] = $this->field_properties['data_length'];
			
			// See if it's a float
			if(strlen($this->field_properties['data_decimals_length']))
			{
				$return['constraint'] .= ', ' . $this->field_properties['data_decimals_length'];
			}
		}
		elseif(is_string($this->field_properties['data_values']) && strlen($this->field_properties['data_values']))
		{
			// A custom string was passed in
			$return['constraint'] = $this->field_properties['data_values'];
		}
		elseif(is_array($this->field_properties['data_values']) && count($this->field_properties['data_values']))
		{
			$return['constraint'] = $this->convert_data_values_for_enum();
		}
		
		// Check for unsigned
		if($this->field_properties['unsigned'] && $this->field_properties['data_type'] === 'INT')
		{
			$return['unsigned'] = true;
		}
		
		// Check for auto-increment
		if($this->is_auto_increment() && $this->field_properties['data_type'] === 'INT')
		{
			$return['auto_increment'] = true;
		}
		
		// Check for null
		if($this->is_null_allowed())
		{
			$return['null'] = true;
		}
		else
		{
			$return['null'] = false;
		}
		
		// Check for default
		if(is_string($this->field_properties['default_value']) && strlen($this->field_properties['default_value']))
		{
			$return['default'] = $this->field_properties['default_value'];
		}
		
		return $return;
	} // end get_field_definition
	
	
	/**
	 * convert_data_values_for_enum:
	 * Convert our array of values for enum (and set) type's values to a string for the DB.
	 * 
	 * @return string
	 */
	protected function convert_data_values_for_enum()
	{
		if(is_array($this->field_properties['data_values']))
		{
			// Convert array to string for use in DB insert statement
			$return = "'" . implode("','", array_keys($this->field_properties['data_values'])) . "'";
		}
		else
		{
			// Nothing to convert, so just return the original value
			$return = $this->field_properties['data_values'];
		}
		
		return($return);
	} // end convert_data_values_for_enum
	
	
	public function get_view()
	{
		if(isset($this->view_file) && strlen($this->view_file))
		{
			return $this->view_file;
		}
		else
		{
			return('admin/fields/' . strtolower(get_class($this)));
		}
	} // end get_view
	
	
	public function set_value($value)
	{
		$this->field_properties['value'] = $value;
	} // end set_value
	
	public function get_value()
	{
		if($this->field_properties['value'] !== null)
		{
			return $this->field_properties['value'];
		}
		else
		{
			return $this->get_default();
		}
	} // end set_value
	
} // end PHLARE_Db_Field
